package com.cheyun.netsalev3.utils

import com.cheyun.netsalev3.utils.api.ApiStores
import okhttp3.*
import okio.Buffer
import java.io.IOException
import java.util.HashMap

/**
 * 后续所有的网络相关公共参数以及缓存配置可以在该类实现
 */

class LogInterceptor : Interceptor {

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): okhttp3.Response {
        val oldRequest = chain.request()
        var newRequestBuild: Request.Builder?
        val method = oldRequest.method()
        var cauthkey = MySharedPreferences.getCauthkey()
        val param = HashMap<String, String>()
        var ip = CommonFunc.getIP()
        var time= (System.currentTimeMillis()/100000).toString()
        time += CommonFunc.getRandomNumberStr(2);
        param.put("ip",ip);
        param.put("time",time);
        val stringBuffer = StringBuffer()
        var postBodyString = ""
        if ("POST" == method) {
            val oldBody = oldRequest.body()
            when (oldBody) {
                is FormBody -> {
                    val formBodyBuilder = FormBody.Builder()
                    formBodyBuilder.add("cauthkey", cauthkey)
                    formBodyBuilder.add("ip", ip)
                    formBodyBuilder.add("time",time)
                    for (i in 0 until oldBody.size()) {
                        param.put(oldBody.name(i),operValue(oldBody.value(i)))
                    }
                    param.put("cauthkey", cauthkey)
                    var items = CommonFunc.sortMap(param);
                    for(item in items){
                        stringBuffer.append(item.value);
                    }
                    Logger.d(TAG,stringBuffer.toString() + ApiStores.KEY)
                    val sign = CommonFunc.textToMD5L32(stringBuffer.toString() + ApiStores.KEY)
//                    Log.d(TAG, stringBuffer.toString()+ ApiStores.KEY + ",sgin:"+sign)
                    formBodyBuilder.add("sign", sign)
                    newRequestBuild = oldRequest.newBuilder()

                    val formBody = formBodyBuilder.build()
                    postBodyString = bodyToString(oldRequest.body())
                    postBodyString += (if (postBodyString.isNotEmpty()) "&" else "") + bodyToString(formBody)
                    newRequestBuild!!.post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString))
                }
                is MultipartBody -> {
                    val oldPartList = oldBody.parts()
                    val builder = MultipartBody.Builder()
                    builder.setType(MultipartBody.FORM)
                    val requestBody1 = RequestBody.create(MediaType.parse("text/plain"), cauthkey)
                    val requestBody2 = RequestBody.create(MediaType.parse("text/plain"), "appName")
                    val requestBody3 = RequestBody.create(MediaType.parse("text/plain"), "appVersion")
                    for (part in oldPartList) {
                        builder.addPart(part)
                        postBodyString += bodyToString(part.body()) + "\n"
                    }
                    postBodyString += bodyToString(requestBody1) + "\n"
//                    postBodyString += bodyToString(requestBody2) + "\n"
//                    postBodyString += bodyToString(requestBody3) + "\n"
                    //              builder.addPart(oldBody);  //不能用这个方法，因为不知道oldBody的类型，可能是PartMap过来的，也可能是多个Part过来的，所以需要重新逐个加载进去
                    builder.addPart(requestBody1)
                    builder.addPart(requestBody2)
                    builder.addPart(requestBody3)
                    newRequestBuild = oldRequest.newBuilder()
                    newRequestBuild!!.post(builder.build())

                    Logger.e(TAG, "MultipartBody," + oldRequest.url())

                }
                else -> {
                    postBodyString = bodyToString(oldRequest.body())
                    newRequestBuild = oldRequest.newBuilder()
                }
            }
        } else {
            // 添加新的参数
            val originalHttpUrl = oldRequest.url()
            for (i in 0 until originalHttpUrl.queryParameterNames().size) {
                param.put(originalHttpUrl.queryParameterName(i), originalHttpUrl.queryParameterValue(i))
            }
            param.put("cauthkey", cauthkey)

            var items = CommonFunc.sortMap(param);
            for(item in items){
                stringBuffer.append(operValue(item.value))
            }

            val sign = CommonFunc.textToMD5L32(stringBuffer.toString() + ApiStores.KEY)
//            Log.d(TAG, stringBuffer.toString()+DmApiStores.KEY + ",sgin:"+sign)
            val commonParamsUrlBuilder = oldRequest.url()
                    .newBuilder()
                    .scheme(oldRequest.url().scheme())
                    .host(oldRequest.url().host())
                    .addQueryParameter("cauthkey", cauthkey)
                    .addQueryParameter("ip", ip)
                    .addQueryParameter("time", time)
                    .addQueryParameter("sign", sign)

            newRequestBuild = oldRequest.newBuilder()
                    .method(oldRequest.method(), oldRequest.body())
                    .url(commonParamsUrlBuilder.build())
        }
        val newRequest = newRequestBuild!!
                .addHeader("Accept", "application/json")
                .addHeader("Accept-Language", "zh")
                .build()

        com.orhanobut.logger.Logger.d("发送请求\nmethod：%s\nurl:%s\n参数:%s", newRequest.method(), newRequest.url(), postBodyString)

        val startTime = System.currentTimeMillis()
//        Log.d(TAG, newRequest.toString())
        val response = chain.proceed(newRequest)
        val endTime = System.currentTimeMillis()
        val duration = endTime - startTime
        val mediaType = response.body()!!.contentType()
        val content = response.body()!!.string()
        val httpStatus = response.code()
//        val logSB = StringBuilder()
//        logSB.append("-------start:$method|")
//        logSB.append(newRequest.toString() + "\n|")
//        logSB.append(if (method.equals("POST", ignoreCase = true)) "post参数{$postBodyString}\n|" else "")
//        logSB.append("httpCode=$httpStatus;Response:$content\n|")
//        logSB.append("----------End:" + duration + "毫秒----------")
//        Log.d(TAG, logSB.toString())

        com.orhanobut.logger.Logger.d("收到响应 %s%s %s毫秒\n请求url:%s\n请求body:%s\n响应body:%s",
                response.code(), response.message(), duration, response.request().url(), postBodyString, content)

        return response.newBuilder()
                .body(okhttp3.ResponseBody.create(mediaType, content))
                .build()
    }

    fun operValue(value:String):String{
        var v = value;
//        v = v.trim().toString()
        v = v.replace("&","&amp;")
//        v = v.replace("\"","&quot;")
        v = v.replace("<","&lt;")
        v = v.replace(">","&gt;")
        return v
    }

    companion object {

        var TAG = "LogInterceptor"
        private fun bodyToString(request: RequestBody?): String {
            try {
                val buffer = Buffer()
                if (request != null)
                    request!!.writeTo(buffer)
                else
                    return ""
                return buffer.readUtf8()
            } catch (e: IOException) {
                return "did not work"
            }

        }
    }
}


